#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

#include <gtk/gtk.h>
#include <glade/glade.h>

#include "8080a.h"

#define GLADE_FILE "dgb-simple.glade"

GladeXML  *main_window;
GtkWidget *widget;
GtkWidget *button;
GtkWindow *window;

EEctx cpu;
bool running;

enum
{
  DASM_ADDRESS = 0,
  DASM_OPCODE_HEX,
  DASM_OPCODE_ASCII,
  NUM_COLS
};

void cpu_init()
{
    reset8080a(&cpu);
}

void gui_show()
{
    widget = glade_xml_get_widget (main_window, "windowDbg");

    gtk_widget_show_all (widget);
}

void toggleButton(GtkButton *button, gchar img_name[], gchar *icon_name, gchar *btn_text)
{
    g_print("%s\n", img_name);

    widget = glade_xml_get_widget(main_window, img_name);

    g_assert(widget != NULL);

    GtkImage *img = GTK_IMAGE(widget);
    gtk_image_set_from_stock(img, icon_name, GTK_ICON_SIZE_BUTTON);
    gtk_button_set_label(button, btn_text);
}

void on_buttonRun_clicked(GtkButton *button, gpointer data)
{
    running = !running;

    if(running)
        toggleButton(button, "imageRun", GTK_STOCK_STOP, "Stop");
    else
        toggleButton(button, "imageRun", GTK_STOCK_EXECUTE, "Run");
}

void on_buttonLoad_clicked(GtkButton *button, gpointer data)
{
    GtkWidget *dialog;

    widget = glade_xml_get_widget (main_window, "windowDbg");

    dialog = gtk_file_chooser_dialog_new ("Open File",
                      GTK_WINDOW(widget),
                      GTK_FILE_CHOOSER_ACTION_OPEN,
                      GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                      GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
                      NULL);

    if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
    {
        gchar *filename;

        filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));

        g_print("%s\n", filename);

        g_free (filename);
    }

    gtk_widget_destroy (dialog);
}

void signal_init()
{
    glade_xml_signal_connect(main_window, "on_buttonRun_clicked",
            G_CALLBACK(on_buttonRun_clicked));

    glade_xml_signal_connect(main_window, "on_buttonLoad_clicked",
            G_CALLBACK(on_buttonLoad_clicked));

    glade_xml_signal_autoconnect (main_window);
}

GtkTreeModel* create_fill_model(void)
{
    GtkListStore *store;
    GtkTreeIter iter;

    store = gtk_list_store_new(NUM_COLS,
                               G_TYPE_UINT,
                               G_TYPE_UINT,
                               G_TYPE_STRING);

    gtk_tree_store_append(GTK_LIST_STORE(store), &iter, NULL);

    gtk_list_store_set(store, &iter,DASM_ADDRESS, 0000,
                                    DASM_OPCODE_HEX, 0x10,
                                    DASM_OPCODE_ASCII, "nop"
                                    -1);

    return GTK_TREE_MODEL(store);
}

void create_view_model(GtkWidget *view)
{
    GtkCellRenderer     *renderer;
    GtkTreeModel        *model;

    renderer = gtk_cell_renderer_text_new();

    gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
                                                -1,
                                                "Address",
                                                renderer,
                                                "text", DASM_ADDRESS,
                                                NULL);

    gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
                                                -1,
                                                "Hex",
                                                renderer,
                                                "text", DASM_OPCODE_HEX,
                                                NULL);

    gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
                                                -1,
                                                "ASCII",
                                                renderer,
                                                "text", DASM_OPCODE_ASCII,
                                                NULL);

    model = create_fill_model();

    gtk_tree_view_set_model (GTK_TREE_VIEW (view), model);

    g_object_unref (model);
}


void tree_init()
{
    GtkWidget *tree;
    tree = glade_xml_get_widget (main_window, "treeviewDasm");

    g_print("POO: %s\n", glade_get_widget_name(tree));

    create_view_model(tree);
}

bool gui_init()
{
    running = false;

    main_window = glade_xml_new (GLADE_FILE, NULL, NULL);

    if(!main_window) return false;

    tree_init();
    signal_init();

    return true;
}

int main (int argc, char *argv[])
{
    cpu_init();

    gtk_init (&argc, &argv);

    if(gui_init()) {
        gui_show();
        gtk_main();
    } else {
        g_printerr("Could not init the GUI.\n");
    }

    return 0;
}
